
package cn.xabad.commons.plist;
import android.util.Log;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.ext.DefaultHandler2;

import java.lang.String;


public class PListXMLHandler extends DefaultHandler2 {

	public static final String TAG = "PListXMLHandler";

	
	public enum ParseMode {
		START_TAG, END_TAG
	}

    
	public interface PListParserListener {
		void onPListParseDone(PList pList, ParseMode mode);
	}

	
	private Stringer stringer;

	
	private PListParserListener parseListener;

	
	private Stringer tempVal;

	
	private PList pList;

	
	protected String key;

	
	public PListXMLHandler() {
		super();
		stringer = new Stringer();
	}

	
	public PList getPlist() {
		return pList;
	}

	
	public void setPlist(PList plist) {
		this.pList = plist;
	}

	
	public PListParserListener getParseListener() {
		return parseListener;
	}

	
	public void setParseListener(PListParserListener parseListener) {
		this.parseListener = parseListener;
	}

	
	public Stringer getTempVal() {
		return tempVal;
	}

	
	public void setTempVal(Stringer tempVal) {
		this.tempVal = tempVal;
	}

	
	@Override
	public void startDocument() throws SAXException {
		super.startDocument();
		tempVal = new Stringer();
		pList = null;
		key = null;
	}

	
	@Override
	public void startElement(String uri, String localName,
			String qName, Attributes attributes) throws SAXException {
		Log.v(stringer.newBuilder().append(TAG).append("#startElement")
                        .toString(),
                stringer.newBuilder()
                        .append("Start Element lname|uri|attr.length :")
                        .append(localName).append(Constants.PIPE).append(uri)
                        .append(Constants.PIPE).append(attributes.getLength())
                        .toString());
		tempVal.newBuilder();
		if (localName.equalsIgnoreCase(Constants.TAG_PLIST)) {
			if (null != pList) {
				
				throw new SAXException(
						"there should only be one PList element in PList XML");
			}
			pList = new PList();
		} else {
			if (null == pList) {
				throw new SAXException(
						"invalid PList - please see http://www.apple.com/DTDs/PropertyList-1.0.dtd");
			}
			if (localName.equalsIgnoreCase(Constants.TAG_DICT) || 
					localName.equalsIgnoreCase(Constants.TAG_PLIST_ARRAY)) {
				try {
					PListObject objToAdd = pList.buildObject(localName, tempVal
							.getBuilder().toString());
					pList.stackObject(objToAdd, key);
				} catch (Exception e) {
					throw new SAXException(e);
				}
			}
		}
	}

	
	@Override
	public void characters(char[] ch, int start, int length)
			throws SAXException {
		Log.v(stringer.newBuilder().append(TAG).append("#characters")
                        .toString(),
                stringer.newBuilder().append(ch).append(Constants.PIPE)
                        .append(start).append(Constants.PIPE).append(length)
                        .append(Constants.PIPE).toString());
		tempVal.getBuilder().append(new String(ch, start, length));
	}

	
	@Override
	public void endElement(String uri, String localName,
			String qName) throws SAXException {
		Log.v(stringer.newBuilder().append(TAG).append("#endElement")
                        .toString(),
                stringer.newBuilder().append("localName|qName|uri|tempVal: ")
                        .append(localName).append(Constants.PIPE).append(qName)
                        .append(Constants.PIPE).append(uri)
                        .append(Constants.PIPE)
                        .append(tempVal.getBuilder().toString()).toString());
		if (localName.equalsIgnoreCase(Constants.TAG_KEY)) {
			key = tempVal.getBuilder().toString().trim();
		} else if (localName.equalsIgnoreCase(Constants.TAG_DICT) || 
				localName.equalsIgnoreCase(Constants.TAG_PLIST_ARRAY)) {
			pList.popStack();
		} else if (!localName.equalsIgnoreCase(Constants.TAG_PLIST)) {
			try {
				PListObject objToAdd = pList.buildObject(localName, tempVal
						.getBuilder().toString());
				pList.stackObject(objToAdd, key);
			} catch (Exception e) {
				throw new SAXException(e);
			}
			key = null;
		} else if (localName.equalsIgnoreCase(Constants.TAG_PLIST)) {
			if (null != parseListener) {
				parseListener.onPListParseDone(pList, ParseMode.END_TAG);
			}
		}
		tempVal.newBuilder();

	}

}
